package com.yiidata.ftpserver.hdfs;

import org.apache.ftpserver.ftplet.FileSystemView;
import org.apache.ftpserver.ftplet.FtpFile;
import org.apache.ftpserver.ftplet.User;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

/**
 * <pre>
 *
 * Created by IntelliJ IDEA.
 * User: zhenqin
 * Date: 15/10/29
 * Time: 12:02
 * To change this template use File | Settings | File Templates.
 *
 * </pre>
 *
 * @author zhenqin
 */
public class HdfsFileSystemView implements FileSystemView {


    private final Logger LOG = LoggerFactory.getLogger(HdfsFileSystemView.class);

    /**
     * 当前登录的 FTP 用户
     */
    private final User user;
    private final FileSystem fs;


    private String rootDir;
    private String currDir;
    private boolean caseInsensitive = false;



    public HdfsFileSystemView(User user, FileSystem fileSystem, boolean caseInsensitive) {
        if (user == null) {
            throw new IllegalArgumentException("user can not be null");
        }
        if (user.getHomeDirectory() == null) {
            throw new IllegalArgumentException("User home directory can not be null");
        }

        this.fs = fileSystem;
        this.caseInsensitive = caseInsensitive;

        String rootDir = user.getHomeDirectory();
        rootDir = HdfsFtpFile.normalizeSeparateChar(rootDir);
        if (!rootDir.endsWith("/")) {
            rootDir = rootDir + '/';
        }
        this.LOG.debug("Native filesystem view created for user \"{}\" with root \"{}\"", user.getName(), rootDir);
        this.rootDir = rootDir;
        this.user = user;
        this.currDir = "/";
    }


    public FtpFile getHomeDirectory() {
        return new HdfsFtpFile("/", fs, new Path(this.rootDir), this.user);
    }

    public FtpFile getWorkingDirectory() {
        FtpFile fileObj = null;
        if (this.currDir.equals("/")) {
            fileObj = new HdfsFtpFile("/", fs, new Path(this.rootDir), this.user);
        } else {
            Path file = new Path(this.rootDir, this.currDir.substring(1));
            fileObj = new HdfsFtpFile(this.currDir, fs, file, this.user);
        }

        return fileObj;
    }

    public FtpFile getFile(String file) {
        String physicalName = HdfsFtpFile.getPhysicalName(this.rootDir, this.currDir, file, this.caseInsensitive);

        Path fileObj = new Path(physicalName);

        String userFileName = physicalName.substring(this.rootDir.length() - 1);
        return new HdfsFtpFile(userFileName, fs, fileObj, this.user);
    }

    public boolean changeWorkingDirectory(String dir) {
        dir = HdfsFtpFile.getPhysicalName(this.rootDir, this.currDir, dir, this.caseInsensitive);

        Path dirObj = new Path(dir);
        try {
            if (!fs.isDirectory(dirObj)) {
                return false;
            }
        } catch (IOException e) {
            return false;
        }

        dir = dir.substring(this.rootDir.length() - 1);
        if (dir.charAt(dir.length() - 1) != '/') {
            dir = dir + '/';
        }

        this.currDir = dir;
        return true;
    }

    public boolean isRandomAccessible() {
        return true;
    }

    @Override
    public void dispose() {

    }
}
